
#include "Tanggal.h"

bool IsTanggalValid(int D, int M, int Y) {
	//Nilai default
	int Valid = true;

	//Validasi
	if ((M < 0) || (M > 12)) Valid = false;
	if ((Y < 0) || (D < 0)) Valid = false;
	if (D > GetMonthDay(M, Y)) Valid = false;

	//Return nilai hasil
	return Valid;
}

date MakeTanggal(int h, int b, int t) {
	//Deklarasi variabel
	date Tanggal;

	//Isi variabel
	Tanggal.DD = h;
	Tanggal.MM = b;
	Tanggal.YY = t;

	//Return jam buatan
	return Tanggal;
}

void BacaTanggalP(date* T) {
	int D, M, Y;

	do {
		printf("[HH/MM/YYYY] : ");
		scanf("%d/%d/%d", &D, &M, &Y);
	} while (!IsTanggalValid(D, M, Y));

	T -> DD = D;
	T -> MM = M;
	T -> YY = Y;
}

void TulisTanggal (date T) {
	printf("%d/%d/%d", T.DD, T.MM, T.YY);
}

int GetMonthDay(int M, int Y) {
	switch (M) {
		case 1:
		case 3:
		case 5:
		case 7:
		case 8:
		case 10:
		case 12:
			return 31;
			break;

		case 4:
		case 6:
		case 9:
		case 11:
			return 30;
			break;

		case 2:
			return ((IsKabisat(Y)) ? 29 : 28);
			break;

		default:
			return 0;
	}
}

date NextDay(date D) {
	if (++D.DD > GetMonthDay(D.MM, D.YY)) {
		D.DD = 1;
		if (++D.MM > 12) {
			D.MM = 1;
			D.YY += 1;
		}
	}

	return D;
}

date PrevDay(date D) {
	if (--D.DD < 1) {
		if (--D.MM < 1) {
			D.MM = 12;
			D.YY -= 1;
		}

		D.DD = GetMonthDay(D.MM, D.YY);
	}

	return D;
}

date NextNDay(date D, int N) {
	int HariTahunIni = ((IsKabisat(D.YY)) ? 366 : 365);

	while (N > HariTahunIni - HariKe(D)) {
		N -= (HariTahunIni - HariKe(D));
		N -= 1;
		D.DD = 1;
		D.MM = 1;
		D.YY += 1;
	}

	while (N > (GetMonthDay(D.MM, D.YY) - D.DD)) {
		N -= GetMonthDay(D.MM, D.YY);
		D.DD = 1;
		D.MM += 1;
	}

	D.DD += N;

	return D;
}

date PrevNDay(date D, int N) {
	while (N >= HariKe(D)) {
		N -= HariKe(D);
		D.DD = 31;
		D.MM = 12;
		D.YY -= 1;
	}

	while (N >= D.DD) {
		N -= D.DD;
		D.MM -= 1;
		D.DD = GetMonthDay(D.MM, D.YY);
	}

	D.DD -= N;

	return D;
}

int HariKe(date D) {
	int TotalHari = 0;
	int i;

	for (i = (D.MM - 1); i > 0; i--) {
		TotalHari += GetMonthDay(i, D.YY);		
	}

	TotalHari += D.DD;

	return TotalHari;
}

bool IsEqD(date D1, date D2) {
	return ((D1.DD == D2.DD) & (D1.MM == D2.MM) && (D1.YY == D2.YY));
}

bool IsBefore(date D1, date D2) {
	if (D1.YY == D2.YY) return (HariKe(D1) < HariKe(D2));
	else return (D1.YY < D2.YY);
}

bool IsAfter(date D1, date D2) {
	if (D1.YY == D2.YY) return (HariKe(D1) > HariKe(D2));
	else return (D1.YY > D2.YY);
}

bool IsKabisat(int Y) {
	return (((Y % 4 == 0) && (Y % 100 != 0)) || (Y % 400 == 0));
}

date GetCurrentDate()
{
	time_t rawtime;
	struct tm * timeinfo;
	char buffer[80];

	time ( &rawtime );
	timeinfo = localtime ( &rawtime );
	
	//Mengambil dari sistem
	strftime (buffer,80,"%d/%m/%Y",timeinfo);
	
	date d;
	sscanf(buffer, "%d/%d/%d", &d.DD, &d.MM, &d.YY);
	return d;
}
